Skip to content

Feat: Unbounded Dependency Pins in requirements.txt (Closes #47)#53

Open
bradjin8 wants to merge 2 commits into
masterfrom
feat/unbounded-dependency-pins
Open

Feat: Unbounded Dependency Pins in requirements.txt (Closes #47)#53
bradjin8 wants to merge 2 commits into
masterfrom
feat/unbounded-dependency-pins

Conversation

@bradjin8
Copy link
Copy Markdown
Collaborator

@bradjin8 bradjin8 commented May 19, 2026

Summary

Closes #47 — Unbounded Dependency Pins in requirements.txt

Changes

Bounded specifiers

  • requirements.txt: added missing upper bound on pillow (>=10.3.0,<11). flask and fpdf2 already had upper bounds from Missing pyproject.toml / No Python Packaging #45; now all three runtime deps are fully bounded.
  • pyproject.toml: same pillow upper bound applied to [project.dependencies] to keep both files in sync.

Lock file (requirements-lock.txt, new)

  • Generated by pip-compile (pip-tools) from the bounded requirements.txt.
  • Pins the full transitive closure to exact versions: flask==3.1.3, fpdf2==2.8.7, pillow==10.4.0, plus blinker, click, colorama, defusedxml, fonttools, itsdangerous, jinja2, markupsafe, werkzeug.
  • Header comment documents the exact pip-compile invocation to regenerate it.

CI (.github/workflows/tests.yml)

  • Both the unittest and typecheck jobs now install from requirements-lock.txt first, then layer the dev-only dep (pytest>=8,<9 / mypy>=1.10,<2) on top.
  • Replaces the old unbounded pip install 'flask>=3.0' 'fpdf2>=2.7' ... invocations.

Dependabot (.github/dependabot.yml, new)

  • Weekly checks for github-actions (keeps the pinned SHA actions current) and pip (opens PRs for new versions within the bounded ranges in requirements.txt).

Scheduled lock-file refresh (.github/workflows/update-lock.yml, new)

  • Runs pip-compile --upgrade every Monday at 08:00 UTC.
  • Opens a PR via peter-evans/create-pull-request with the refreshed requirements-lock.txt for review before merging.
  • Also triggerable manually from the Actions tab.

Acceptance criteria checklist

  • All runtime deps in requirements.txt have both lower and upper bounds
  • requirements-lock.txt generated and committed
  • CI installs from the lock file for deterministic test results
  • Dependabot + weekly scheduled workflow documented and configured for lock-file maintenance
  • Upper bounds are conservative (current known-compatible major versions)

Summary by CodeRabbit

  • Chores
    • Reproducible, deterministic Python builds using a committed dependency lockfile.
    • CI/test workflows now install pinned dependencies from the lockfile for consistent test environments.
    • Automated weekly dependency refreshes with pull-request creation for dependency updates.
    • Updated Pillow dependency to a newer, bounded major-version range for improved security and stability.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3aeb83a8-5610-4b63-90f6-ceebf27416cf

📥 Commits

Reviewing files that changed from the base of the PR and between dd36d08 and 623370c.

📒 Files selected for processing (4)
  • .github/workflows/update-lock.yml
  • pyproject.toml
  • requirements-lock.txt
  • requirements.txt
✅ Files skipped from review due to trivial changes (1)
  • requirements-lock.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/update-lock.yml

📝 Walkthrough

Walkthrough

Adds bounded Pillow constraints (>=12.2.0,<13), a pip-compile-generated requirements-lock.txt, a scheduled/manual update-lock.yml workflow to regenerate the lock and open PRs, Dependabot config for weekly Actions and pip updates, and CI jobs updated to install from the lockfile plus tool-specific pins.

Changes

Deterministic dependency management via lock file

Layer / File(s) Summary
Dependency bounds
pyproject.toml, requirements.txt
pillow is changed to >=12.2.0,<13 in both manifest files.
Lock file generation workflow
.github/workflows/update-lock.yml, requirements-lock.txt
Adds update-lock.yml (weekly cron + manual dispatch) that sets up Python 3.12, installs pip-tools, runs pip-compile --upgrade --allow-unsafe, restores a pinned header if omitted, commits the updated requirements-lock.txt, and opens a PR when it changes. The repository includes a pip-compile-generated requirements-lock.txt.
Automated dependency update management
.github/dependabot.yml
Introduces Dependabot config for github-actions and pip ecosystems to run weekly on Mondays, with updates labeled dependencies and comments about using pinned action SHAs and regenerating the lockfile after merges.
CI integration with locked dependencies
.github/workflows/tests.yml
unittest and typecheck jobs now install runtime packages from requirements-lock.txt, then add pytest>=8,<9 or mypy>=1.10,<2 respectively, replacing prior ad-hoc direct package installations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • timon0305
  • wpak-ai

Poem

🐰 I nibble pins and chase the lock,
Versions steady — no surprise to shock,
Pip compiles, Dependabot hops in tune,
CI hums safely beneath the moon,
A tiny rabbit cheers for stable noon.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title mentions 'Unbounded Dependency Pins' but the PR actually implements bounded pins and lock files, directly contradicting the stated objectives. Revise title to reflect actual changes, e.g., 'Feat: Add bounded dependency pins and lock file management (Closes #47)' or 'Feat: Implement deterministic CI with lock file and dependency bounds'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed All five coding-related acceptance criteria from #47 are met: runtime dependencies bounded [#47], lock file generated and committed [#47], CI uses lock file [#47], Dependabot configured for updates [#47], and conservative bounds applied [#47].
Out of Scope Changes check ✅ Passed All changes align with #47 requirements: dependency bounding, lock file generation, CI integration, and automation configuration. No unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/unbounded-dependency-pins

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/update-lock.yml:
- Line 50: Replace the floating tag for the GitHub Action usage of
peter-evans/create-pull-request (currently "uses:
peter-evans/create-pull-request@v7") with a specific immutable commit SHA;
locate the "uses: peter-evans/create-pull-request@v7" line in the workflow, find
the latest verified commit SHA for that action (from the action's repository
tags or the marketplace), and update the string to "uses:
peter-evans/create-pull-request@<commit-sha>" so the workflow is pinned to a
specific commit instead of the v7 tag.

In `@requirements-lock.txt`:
- Line 16: The lockfile currently pins pillow==10.4.0 which contains multiple
high-severity vulnerabilities; update the upstream constraint that produced this
lock (the requirement spec "pillow>=10.3.0,<11") to allow Pillow 12.x (e.g.,
change to "pillow>=12.1.1" or "pillow>=12.2.0") after verifying that dependent
packages (notably fpdf2) are compatible with Pillow 12.2.0, then regenerate the
lock file (re-run your dependency lock/compile step) so the lock reflects
pillow==12.2.0 (or the chosen 12.x release) and ensure CI/tests pass.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67859c4b-d312-4b72-b22c-53f21ba2fc9c

📥 Commits

Reviewing files that changed from the base of the PR and between 04d57fc and dd36d08.

📒 Files selected for processing (6)
  • .github/dependabot.yml
  • .github/workflows/tests.yml
  • .github/workflows/update-lock.yml
  • pyproject.toml
  • requirements-lock.txt
  • requirements.txt

Comment thread .github/workflows/update-lock.yml Outdated
Comment thread requirements-lock.txt Outdated
@bradjin8 bradjin8 requested a review from clean6378-max-it May 19, 2026 14:36
@bradjin8 bradjin8 self-assigned this May 19, 2026
@clean6378-max-it
Copy link
Copy Markdown
Collaborator

README.md — Document lock-file workflow for contributors: CI uses requirements-lock.txt; how to regenerate (pip-compile command from the lock header); Dependabot + “Update dependency lock file” Actions. (Issue #47 asks for a documented update process; it lives only in YAML comments today.)

.github/workflows/tests.yml (new step) — Add a lock freshness check, e.g. run pip-compile with the same flags as update-lock.yml and fail if requirements-lock.txt differs (git diff --exit-code). (Prevents requirements.txt / pyproject.toml edits without regenerating the lock while CI still passes.)

.github/workflows/update-lock.yml:42-46 — Fix the “Restore header comment” step: HEADER is single-quoted, so \n is literal, not newline; printf '%s\n' "$HEADER" will write one malformed line when the workflow prepends the header after pip-compile --no-header. (The committed lock file is correct today; the first automated lock refresh will corrupt the header.)

.github/dependabot.yml + update-lock.yml — Clarify the two-path maintenance model: Dependabot pip PRs may bump bounds in requirements.txt but do not refresh the lock; merging those should trigger (or be followed by) the lock workflow. (Reduces drift between bounds and pinned CI installs.)

requirements.txt / pyproject.toml — Consider compiling from pyproject.toml (pip-compile pyproject.toml) or adding a CI check that [project.dependencies] matches requirements.txt. (Single source of truth; today sync is comment-only.)

requirements-lock.txt — colorama is pinned as a transitive dep (Windows-oriented); harmless for reproducibility on Linux CI but matches the eval’s portability note. (No action required unless you want platform-specific lock files.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unbounded Dependency Pins in requirements.txt

2 participants